#include "loadTestCase.h"


CasePair * creatCasePair(int backpack_volume, int * item_values, int * item_weights){
    CasePair * pair = (CasePair *) malloc(sizeof(CasePair));
    pair->backpack_volume = backpack_volume;
    pair->item_values = item_values;
    pair->item_weights = item_weights;
    pair->nextCase = NULL;
    return pair;
}


CaseSuite * creatCaseSuite(){
    CaseSuite * suite = (CaseSuite *) malloc(sizeof(CaseSuite));
    suite->length = 0;
    suite->head = creatCasePair(-1, NULL, NULL);
    suite->tail = creatCasePair(-1, NULL, NULL);
    suite->temp = suite->head;

    suite->temp = suite->head;
    suite->head->nextCase = suite->tail;
    return suite;
}


CaseSuite * appendPair(CaseSuite * suite, CasePair * pair){
    pair->nextCase = suite->temp->nextCase;
    suite->temp->nextCase = pair;
    suite->temp = pair;
    suite->length += 1;
    return suite;
}


bool donePair(CasePair * pair){
    if (NULL != pair->item_values)
        free(pair->item_values);
    if (NULL != pair->item_weights)
    free(pair->item_weights);
    free(pair);
    return true;
}


bool doneSuite(CaseSuite * suite){
    for (int i=0; i < suite->length+2; i++){
        suite->temp = suite->head;
        suite->head = suite->head->nextCase;
        donePair(suite->temp);
    }
    free(suite);
    return true;
}

int * str2NumList(char * str, char split_char){
    int length = strlen(str);
    // * 默认有一个值
    int number_nums = 1;
    for (int i=0; i<length; i++)
        if (*(str+i) == split_char)
            number_nums ++;

    int temp_num = 0;
    int * num_list = (int *) malloc(sizeof(int) * (number_nums + 1));
    // * 初始化 num_list 并且把num_list 的第一个元素设置成num_list的长度
    memset(num_list, 0, number_nums);
    *(num_list + 0) = number_nums + 1;

    for (int i=0, j=1; i<= strlen(str); i++){
        // * 等于分割符
        if (*(str + i) == split_char){
            *(num_list + j++) = temp_num;
            temp_num = 0;
            continue;
        }

        // * 遇到\0结尾的末尾
        if (*(str + i) == '\0'){
            *(num_list + j++) = temp_num;
            temp_num = 0;
            return num_list;
        }

        // * 遇到\n结尾的末尾
        if (*(str + i) == '\n'){
            *(num_list + j++) = temp_num;
            temp_num = 0;
            return num_list;
        }

        // * 此外遇到的不是数字报错
        if (0 <=*(str+i) -'0'  and *(str + i) -'0' <= 9)
            temp_num = temp_num * 10 + *(str + i) - '0';
        else{
            sprintf(error_message, "%s：非法字符 %c，在第%d列", __func__, *(str + i), i);
            printf("%s\n", error_message);
            exit(-1);
        }
    }
    return num_list;
}


/*
* * 读取时注意，每一个测试样例要求，第一行是背包容量，第二行是物体重量，第三行是物体价值
* * 如果skip_value指定为true，则跳过价值，此时每一个测试样例只有两行
* * 注意，读取得到的每一个CasePair的weights和value都是长度+1，第0位是总长度
*/
CaseSuite * initTestSuite(char * test_filepath, char split_char, bool skip_value){
    sprintf(info_message, "%s：正在读取 %s", __func__, test_filepath);
    printf("%s\n", blue(info_message));

    FILE * fp;
    if (NULL == (fp = fopen(test_filepath, "r"))){
        sprintf(error_message, "%s：文件打开错误 %s", __func__,test_filepath);
        perror(red(error_message));
        exit(-1);
    }

    char * buffer = (char *) malloc(sizeof(char) * MAXIMUM_READ_LENGTH);
    if (NULL == buffer){
        sprintf(error_message, "%s：内存分配失败 %s", __func__, test_filepath);
        perror(red(error_message));
        exit(-1);
    }

    int total_read_lines = 0;
    int lines_of_pair = skip_value ? 2 : 3;
    CasePair * pair;
    CaseSuite * suite = (CaseSuite *) creatCaseSuite();
    while (NULL != fgets(buffer, MAXIMUM_READ_LENGTH, fp)){
        // * 如果是注释直接跳过
        if (buffer[0] == '#' or buffer[0] == '/')
            continue;

        // * 读取到一个CasePair，插入到CaseSuite中
        if (total_read_lines % lines_of_pair == 0){
            // * 只要不是第零行，则插入之后新开一个pair
            if (total_read_lines != 0)
                suite = appendPair(suite, pair);
            pair = (CasePair *) creatCasePair(*((int *) str2NumList(buffer, split_char)+1), NULL, NULL);
            total_read_lines++;
            continue;
        }
        else if ( total_read_lines % lines_of_pair == 1 ){
            // * 第一行是weight
            pair->item_weights = (int *) str2NumList(buffer, split_char);
            total_read_lines++;
        }
        else{
            // * 第二行是value
            pair->item_values = (int *) str2NumList(buffer, split_char);
            total_read_lines++;
        }
    }
    // * 把最后一个pair 添加进去
    suite = appendPair(suite, pair);
    fclose(fp);

    sprintf(info_message, "%s：读取完成%s", __func__, test_filepath);
    printf("%s\n", blue(info_message));
    return suite;
}